package org.methodbox.extractor;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 *
 * @author Christian
 */
public class Parser {

    private BufferedReader input;

    private BufferedWriter headeredOutput;

    private BufferedWriter unheaderedOutput;

    private String year;

    private int[] columns;

    private void openInput(String inputFileName) throws ExtractorException{
        try {
            File inputFile = new File(inputFileName);
            if (inputFileName.toLowerCase().endsWith(".zip")){
                FileInputStream raw = new FileInputStream(inputFile);
                ZipInputStream zip = new ZipInputStream(raw);
                ZipEntry entry = zip.getNextEntry();
                input = new BufferedReader (new InputStreamReader(zip));
            } else {
                input = new BufferedReader (new FileReader(inputFile));
            }
        } catch (IOException ex) {
            throw new ExtractorException(ex);
        }
    }

    private void openOutput(String columnsToPick, String exportName, String year, String outputDirName) throws ExtractorException{
        try {
            File outputDir = new File(outputDirName);
            if (outputDir.exists()){
                if (outputDir.isFile()){
                    throw new ExtractorException(outputDirName + " points to a file.");
                }
            } else {
                outputDir.mkdirs();
            }
            File headeredFile = new File(outputDir, exportName + ".csv");
            headeredOutput = new BufferedWriter(new FileWriter(headeredFile));
            File unheaderedFile = new File(outputDir, exportName + ".txt");
            unheaderedOutput = new BufferedWriter(new FileWriter(unheaderedFile));
            headeredOutput.write("id\t" + year + "\t" + columnsToPick+ "\n");
        } catch (IOException ex) {
            throw new ExtractorException(ex);
        //} catch (FileNotFoundException ex) {
        //    throw new ExtractorException(ex);
        }
    }

    private void findColumns(String columnsToPick) throws ExtractorException{
        try {
            String[] columnNames = columnsToPick.split(",");
            columns = new int[columnNames.length];
            String headLine = input.readLine();
            String[] heads = headLine.split("\t");
            for (int i = 0; i< columnNames.length; i++){
                boolean found = false;
                //Try exact match
                for (int j = 0; j< heads.length; j++){
                    if (columnNames[i].equals(heads[j])){
                        System.out.println("Found exact match for "+ columnNames[i]);
                        columns[i] = j;
                        found = true;
                    }
                }
                if (!found){
                    //Try igonre case
                    for (int j = 0; j< heads.length; j++){
                        if (columnNames[i].equalsIgnoreCase(heads[j])){
                            System.out.println("Found ignore case match for "+ columnNames[i] +
                                    " ~ "+ heads[j]);
                            columns[i] = j;
                            found = true;
                        }
                    }
                }
                //TO DO more fuzzier mapping
                //Give up
                if (!found){
                    throw new ExtractorException("Unable to find column " + columns[i]);
                }
            }
        } catch (IOException ex) {
            throw new ExtractorException(ex);
        }
    }

    private void close() throws ExtractorException{
        try {
            input.close();
            headeredOutput.close();
            unheaderedOutput.close();
        } catch (IOException ex) {
             throw new ExtractorException(ex);
        }
    }

    public Parser(String inputFileName, String columnsToPick, String exportName, String year, String outputDirName)
            throws ExtractorException{
        this.year = year;
        openInput(inputFileName);
        openOutput(columnsToPick, exportName, year, outputDirName);
        findColumns(columnsToPick);
    }

    public void run() throws ExtractorException{
        try {
            int count = 0;
            while (input.ready()) {
                String inputLine = input.readLine();
                String[] inputs = inputLine.split("\t");
                count++;
                StringBuffer output = new StringBuffer(count + "\t" + year);
                for (int i = 0; i < columns.length; i++){
                    output.append("\t");
                    output.append(columns[i]);
                }
                output.append("\n");
                headeredOutput.write(output.toString());
                unheaderedOutput.write(output.toString());
            }
        } catch (IOException ex) {
             throw new ExtractorException(ex);
        }
       close();
    }

    public static void main( String[] args ) throws ExtractorException
    {
        //tring inputFileName = "C:/Ruby/elab/java/extractor/Data/small.data";
        //tring columnsToPick = "Afford4,Amthb";
        String inputFileName = "C:/Ruby/elab/java/extractor/Data/large.zip";
        String columnsToPick = "CHILDREN,INFANTS,SRCINC03,YTAKE092,EVERJOB,INDCULT3,SDQCHK,NSSEC8,DRMTH06,HSERIAL,INDCULT3,";
        String exportName = "test";
        String year = "2010";
        String outputDirName = "C:/Ruby/elab/java/extractor/Results";
        Parser parser = new Parser(inputFileName, columnsToPick, exportName, year, outputDirName);
        parser.run();
    }

}
